using AutoMapper;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Work.API.Applications.Write.Commands;
using Work.Domain.DrugManage;
using Work.ErrorCode;
using Work.Infrastructure.Interfaces;

namespace Work.API.Applications.Write.CommandHandlers
{
    /// <summary>
    /// 创建检药单处理器（用于查看检药单模块）
    /// 业务逻辑：
    /// 1. 验证处方明细是否存在
    /// 2. 检查是否已存在检药单（一个处方明细只能有一个检药单）
    /// 3. 创建检药单记录
    /// </summary>
    public class CreateInspectionCommandHandler : IRequestHandler<CreateInspectionCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<DrugInspection> _inspectionRepo;
        private readonly IBaseRepository<Domain.PrescriptionItem> _prescriptionItemRepo;
        private readonly IBaseRepository<Domain.Appintment> _appointmentRepo;
        private readonly IBaseRepository<Domain.Patient> _patientRepo;
        private readonly IMapper _mapper;

        public CreateInspectionCommandHandler(
            IBaseRepository<DrugInspection> inspectionRepo,
            IBaseRepository<Domain.PrescriptionItem> prescriptionItemRepo,
            IBaseRepository<Domain.Appintment> appointmentRepo,
            IBaseRepository<Domain.Patient> patientRepo,
            IMapper mapper)
        {
            _inspectionRepo = inspectionRepo;
            _prescriptionItemRepo = prescriptionItemRepo;
            _appointmentRepo = appointmentRepo;
            _patientRepo = patientRepo;
            _mapper = mapper;
        }

        public async Task<ApiResult<int>> Handle(CreateInspectionCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<int>();

            try
            {
                // 1. 验证处方明细是否存在
                var prescriptionItem = await _prescriptionItemRepo.GetById(request.PrescriptionItemId);
                if (prescriptionItem == null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "处方明细不存在";
                    result.Data = 0;
                    return result;
                }

                // 2. 检查是否已存在检药单（一个处方明细只能有一个检药单）
                var existingInspection = await _inspectionRepo.GetAll()
                    .FirstOrDefaultAsync(x => x.PrescriptionItemId == request.PrescriptionItemId, cancellationToken);

                if (existingInspection != null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "该处方明细已存在检药单";
                    result.Data = existingInspection.InspectionId;
                    return result;
                }

                // 3. 从处方明细中获取正确的信息（如果前端未提供）
                var appointmentId = request.AppointmentId > 0 ? request.AppointmentId : prescriptionItem.AppointmentId;
                var patientId = request.PatientId > 0 ? request.PatientId : prescriptionItem.PatientId;
                var registrationNum = !string.IsNullOrWhiteSpace(request.RegistrationNum) 
                    ? request.RegistrationNum 
                    : prescriptionItem.RegistrationNum;
                var drugName = !string.IsNullOrWhiteSpace(request.DrugName) 
                    ? request.DrugName 
                    : prescriptionItem.MedicineName;

                // 验证AppointmentId是否存在
                if (appointmentId <= 0)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "预约编号无效";
                    result.Data = 0;
                    return result;
                }

                var appointment = await _appointmentRepo.GetById(appointmentId);
                if (appointment == null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"预约编号 {appointmentId} 不存在";
                    result.Data = 0;
                    return result;
                }

                // 验证PatientId是否存在
                if (patientId <= 0)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "患者ID无效";
                    result.Data = 0;
                    return result;
                }

                var patient = await _patientRepo.GetById(patientId);
                if (patient == null)
                {
                    result.Code = ApiEnum.失败;
                    result.Message = $"患者ID {patientId} 不存在";
                    result.Data = 0;
                    return result;
                }

                // 4. 处理DrugId：如果为0或null，设置为null（避免外键约束错误）
                int? drugId = null;
                if (request.DrugId.HasValue && request.DrugId.Value > 0)
                {
                    drugId = request.DrugId.Value;
                }

                // 5. 创建检药单记录
                var inspection = new DrugInspection
                {
                    PrescriptionItemId = request.PrescriptionItemId,
                    AppointmentId = appointmentId,
                    PatientId = patientId,
                    RegistrationNum = registrationNum,
                    PatientName = request.PatientName,
                    CardNumber = request.CardNumber,
                    DrugId = drugId,
                    DrugName = drugName,
                    InspectionStatus = "待检查", // 初始状态为待检查
                    IsDispensed = false,
                    CreateTime = DateTime.Now,
                    Remarks = request.Remarks
                };

                var rows = await _inspectionRepo.AddAsync(inspection);

                if (rows > 0)
                {
                    result.Code = ApiEnum.成功;
                    result.Message = "检药单创建成功";
                    result.Data = inspection.InspectionId;
                }
                else
                {
                    result.Code = ApiEnum.失败;
                    result.Message = "检药单创建失败";
                    result.Data = 0;
                }
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.失败;
                result.Message = $"创建失败：{ex.Message}";
                // 记录内部异常信息，便于调试
                if (ex.InnerException != null)
                {
                    result.Message += $" 内部错误：{ex.InnerException.Message}";
                }
                result.Data = 0;
            }

            return result;
        }
    }
}

